package com.example.exam.annotation;

import com.example.exam.entity.temp.MailMessage;
import com.example.exam.utils.MailUtils;
import com.example.exam.utils.RandomUtils;
import com.example.exam.utils.RedisUtils;
import lombok.extern.log4j.Log4j2;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @author zhang
 */
@Aspect
@Component
@Log4j2
public class EmailSender {
    private final RedisUtils redisUtils;
    private final MailUtils mailUtils;

    @Autowired
    public EmailSender(MailUtils mailUtils, RedisUtils redisUtils) {
        this.mailUtils = mailUtils;
        this.redisUtils = redisUtils;
    }

    @Pointcut("@annotation(com.example.exam.annotation.SendCaptchaEmail)")
    public void sendEmail() {
    }

    @Before("sendEmail()")
    public void sendEmailBeforeMethodExecution(JoinPoint joinPoint) throws RuntimeException {
        // 在方法执行前触发发送邮件的逻辑
        // 可以在此处编写发送邮件的代码
        Method method = getCurrentMethod(joinPoint);
        SendCaptchaEmail sendCaptchaEmail = method.getAnnotation(SendCaptchaEmail.class);
        String prefix = sendCaptchaEmail.prefix();
        String to = !MailUtils.isEmailValid(sendCaptchaEmail.to()) ? sendCaptchaEmail.to() : getMail(joinPoint, sendCaptchaEmail);
        if (to == null) {
            throw new RuntimeException("没有符合要求的参数");
        }
        if (prefix.equals(MailMessage.CAPTCHA)) {
            sendCaptchaEmail(to);
        }
    }

    private Method getCurrentMethod(JoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        return methodSignature.getMethod();
    }

    private String getMail(JoinPoint joinPoint, SendCaptchaEmail annotation) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = methodSignature.getParameterNames();
        Object[] parameterValues = joinPoint.getArgs();
        String temp = "{*}";
        for (int i = 0; i < parameterNames.length; i++) {
            log.info("parameterName[{}] = {}", i, parameterValues[i]);
            if (parameterValues[i] instanceof String) {
                if (temp.replace("*", parameterNames[i]).equals(annotation.to())) {
                    String param = parameterValues[i].toString().replace("\"", "");
                    return !MailUtils.isEmailValid(param) ? param : null;
                }
            }
        }
        return null;
    }

    private void sendCaptchaEmail(String mail) throws RuntimeException {
        String captcha = RandomUtils.getRandomString(6);
        if (MailUtils.isEmailValid(mail)) {
            log.info("不正确的邮箱格式");
            throw new RuntimeException("不正确的邮箱格式");
        }
        if (redisUtils.get(mail) != null && !redisUtils.get(mail).isEmpty()) {
            log.info("获取验证码频繁,请稍后再试");
            throw new RuntimeException("获取验证码频繁，请稍后再试");
        }
        mailUtils.sendMail(mail, MailMessage.CAPTCHA_HEAD,
                MailMessage.CAPTCHA_BODY(captcha));
        redisUtils.set(mail, captcha, 15);
        log.info("获取验证码成功");
    }
}
